home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / 3DTOSHI2.ZIP / mpgfx / source / Gfxvesa.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  12.4 KB  |  513 lines

  1.  
  2. // gfxvesa.cpp
  3. //
  4. // Copyright (c) 1995 by Toshiaki Tsuji, all rights reserved.
  5.  
  6. #include "stdgfx.h" 
  7. #include "gfxvesa.h"
  8. #include "gfxdpmi.h"
  9. #include "lgfxvsa.h"
  10. #include "lgfxdib.h"
  11.  
  12. VESADRIVER::VESADRIVER ()
  13.   {
  14.     VESABlock = new VESABLOCK;
  15.   } // End of Constructor for VESADRIVER
  16.  
  17. VESADRIVER::~VESADRIVER ()
  18.   {
  19.     delete VESABlock;
  20.     VESABlock = NULL;
  21.   } // End of Destructor for VESADRIVER
  22.  
  23. BOOLEAN VESADRIVER::DetectVESA ()
  24.   {
  25.     #if defined (__FORWINDOWS__)
  26.       return FAILURE;
  27.     #elif defined (__FOROS2__)
  28.       return FAILURE;
  29.     #elif defined (__FORDOS__)
  30.       union REGS Regs;
  31.       struct SREGS SegRegs;
  32.  
  33.       Regs16.ax = 0x4F00;
  34.       segread ( &SegRegs );
  35.  
  36.       #if defined (__32BIT__)
  37.         #ifndef __FORPOWERPACK__
  38.           VESABLOCK far* BlockPtr;
  39.           INT NumPara;
  40.           WORD Selector,Segment;
  41.  
  42.           NumPara = (512+15)/16;
  43.  
  44.           DPMI.AllocateDOSMemory ( NumPara, &Selector, &Segment );
  45.           Regs.x.edi = 0;
  46.           SegRegs.es = Segment;
  47.           BlockPtr = (VESABLOCK far*)MK_FP(Selector,0);
  48.           DPMI.Int86x ( INT_VESA, &Regs, &Regs, &SegRegs );
  49.           _fmemcpy ( (VESABLOCK far*)VESABlock, BlockPtr, 512 );
  50.           DPMI.FreeDOSMemory ( Selector );
  51.         #endif
  52.       #elif defined (__FORPWPK16__)
  53.         VESABLOCK far* BlockPtr;
  54.         INT NumPara;
  55.         WORD Selector,Segment;
  56.  
  57.         NumPara = (512+15)/16;
  58.  
  59.         DPMI.AllocateDOSMemory ( NumPara, &Selector, &Segment );
  60.         Regs16.di = 0;
  61.         SegRegs.es = Segment;
  62.         BlockPtr = (VESABLOCK far*)MK_FP(Selector,0);
  63.         DPMI.Int86x ( INT_VESA, &Regs, &Regs, &SegRegs );
  64.         _fmemcpy ( (VESABLOCK far*)VESABlock, BlockPtr, 512 );
  65.         DPMI.FreeDOSMemory ( Selector );
  66.       #else
  67.         strncpy ( VESABlock->ID, "VBE2", 4 );
  68.         Regs16.di = FP_OFF(VESABlock);
  69.         SegRegs.es = FP_SEG(VESABlock);
  70.         INTERRUPTx ( INT_VESA, &Regs, &Regs, &SegRegs );
  71.       #endif
  72.       
  73.       if (Regs8.al!=0x4F)
  74.         return FAILURE;
  75.       if (Regs8.ah!=0)
  76.         return FALSE;
  77.       if (strncmp(VESABlock->ID,"VESA",4))
  78.         return FALSE;
  79.        return SUCCESS;
  80.     #endif
  81.   } // End of DetectVESA for VESADRIVER
  82.  
  83. BOOLEAN VESADRIVER::SetVESAMode ( LONG ModeNumber )
  84.   {
  85.     #if defined (__FORWINDOWS__)
  86.       if (ModeNumber)
  87.         {}
  88.       return SUCCESS;
  89.     #elif defined (__FOROS2__)
  90.       if (ModeNumber)
  91.         {}
  92.       return SUCCESS;
  93.     #elif defined (__FORDOS__)
  94.       union REGS Regs;
  95.       Regs16.ax = 0x4F02;
  96.       Regs16.bx = (SHORT)ModeNumber;
  97.  
  98.       INTERRUPT ( INT_VESA, &Regs, &Regs );
  99.  
  100.       if (Regs8.al!=0x4F)
  101.         return FAILURE;
  102.       if (Regs8.ah!=0)
  103.         return FALSE;
  104.       SetVESASelector ( SELECTOR_VIDEO );
  105.       return SUCCESS;
  106.     #endif
  107.   } // End of SetVESAMode for VESADRIVER
  108.  
  109. BOOLEAN VESADRIVER::SetVESABank ( LONG Bank )
  110.   {
  111.     #if defined (__FORWINDOWS__)
  112.       if (Bank)
  113.         {}
  114.       return SUCCESS;
  115.     #elif defined (__FOROS2__)
  116.       if (Bank)
  117.         {}
  118.       return SUCCESS;
  119.     #elif defined (__FORDOS__)
  120.       union REGS Regs;
  121.       Regs16.ax = 0x4F05;
  122.       Regs16.bx = 0;
  123.       Regs16.cx = 0;
  124.       Regs16.dx = (SHORT)Bank;
  125.  
  126.       INTERRUPT ( INT_VESA, &Regs, &Regs );
  127.  
  128.       if (Regs8.al!=0x4F)
  129.         return FAILURE;
  130.       if (Regs8.ah!=0)
  131.         return FALSE;
  132.       return SUCCESS;
  133.     #endif
  134.   } // End of SetVESABank for VESADRIVER
  135.  
  136. BOOLEAN VESADRIVER::SetRowSize ( LONG Size )
  137.   {
  138.     #if defined (__FORWINDOWS__)
  139.       if (Size)
  140.         {}
  141.       return SUCCESS;
  142.     #elif defined (__FOROS2__)
  143.       if (Size)
  144.         {}
  145.       return SUCCESS;
  146.     #elif defined (__FORDOS__)
  147.       union REGS Regs;
  148.       Regs16.ax = 0x4F06;
  149.       Regs16.bx = 0;
  150.       Regs16.cx = (SHORT)Size;
  151.  
  152.       INTERRUPT ( INT_VESA, &Regs, &Regs );
  153.  
  154.       if (Regs8.al!=0x4F)
  155.         return FAILURE;
  156.       if (Regs8.ah!=0)
  157.         return FALSE;
  158.       return SUCCESS;
  159.     #endif
  160.   } // End of SetRowSize for VESADRIVER
  161.  
  162. BOOLEAN VESADRIVER::SetUp ( DISPLAYDATA *Data )
  163.   {
  164.     if (Data)
  165.       {}  
  166.     #if defined (__FORWINDOWS__)
  167.       return SUCCESS;
  168.     #elif defined (__FOROS2__)
  169.       return SUCCESS;
  170.     #elif defined (__FORDOS__)
  171.       //if (DetectVESA()==FAILURE)
  172.       //  return FAILURE;
  173.  
  174.       LONG ModeNumber;
  175.  
  176.       ModeNumber = ModeTable[Data->Mode].ModeNumber;
  177.  
  178.       if (SetVESAMode(ModeNumber)==FAILURE)
  179.         return FAILURE;
  180.  
  181.       if (SetVESABank ( 0 )==FAILURE)
  182.         return FAILURE;
  183.  
  184.       if (SetRowSize(1024)==FAILURE)
  185.         return FAILURE;
  186.  
  187.       CurMode = Data->Mode;
  188.  
  189.       Width = ModeTable[Data->Mode].Width;
  190.       Height = ModeTable[Data->Mode].Height;
  191.       BitSize = ModeTable[Data->Mode].BitSize;
  192.  
  193.       BytesPerRow = 1024;
  194.  
  195.       SetVESAData ( Width, Height, 1024 );
  196.  
  197.       Clear ( HVGA, 0 );
  198.  
  199.       return SUCCESS;
  200.     #endif
  201.   } // End of SetUp for VESADRIVER
  202.  
  203. VOID VESADRIVER::Reset ()
  204.   {
  205.     #if defined (__FORWINDOWS__)
  206.     #elif defined (__FOROS2__)
  207.     #elif defined (__FORDOS__)
  208.       union REGS Regs;
  209.       Regs8.ah = 0;
  210.       Regs8.al = 3;
  211.       INTERRUPT ( INT_VIDEO, &Regs, &Regs );
  212.  
  213.       Width = ModeTable[M80x25x16].Width;
  214.       Height = ModeTable[M80x25x16].Height;
  215.       BitSize = ModeTable[M80x25x16].BitSize;
  216.     #endif
  217.   } // End of Reset for VGADRIVER
  218.  
  219. VOID VESADRIVER::Clear ( HDISPLAY hDisplay, LONG Color )
  220.   {
  221.     if (hDisplay)
  222.       {}
  223.     if (BitSize==8)
  224.       VESAClear256 ( (BYTE)Color );
  225.   } // End of Clear for VESADRIVER
  226.  
  227. VOID VESADRIVER::DisplayImage ( IMAGE *Image, LONG Sx, LONG Sy,
  228.                                 LONG Wd, LONG Ht, HDISPLAY Dest,
  229.                                 LONG Cx, LONG Cy, LONG DestWd, LONG DestHt )
  230.   {
  231.     BYTE *SrcBuffer;
  232.     LONG Format;
  233.  
  234.     if (Dest)
  235.       {}
  236.     Format = Image->GetFormat();
  237.     SrcBuffer = Image->SetOffset ( Sx, Sy );
  238.     if (BitSize==8)
  239.       {
  240.         if ((MagH==DivH)&&(MagV==DivV))
  241.           {
  242.             if (Format==IMAGE_8BIT)
  243.               VESACopy256To256 ( SrcBuffer, Image->GetRowInc (), Wd, Ht,
  244.                                  Cx, Cy );
  245.           } // End if
  246.         else
  247.           {
  248.             BYTE *DestBuffer;
  249.             LONG Offset;
  250.             LONG Page;
  251.             
  252.             #if defined (__32BIT__)
  253.               DestBuffer = (BYTE*)0xA0000;
  254.             #else
  255.               DestBuffer = (BYTE*)MK_FP(SELECTOR_VIDEO,0);
  256.             #endif
  257.  
  258.             Offset = Cy*BytesPerRow+Cx;
  259.  
  260.             Page = Offset >> 16;
  261.             Offset &= 0xFFFF;
  262.             
  263.             SetVESABank ( Page ); 
  264.     
  265.             WORD Error = 0;
  266.             DWORD AddError = (((LONG)DivH<<16)/MagH);
  267.  
  268.             INT i; 
  269.             for (i=0;i<DestHt;i++)
  270.               {
  271.                 ScaleBlt256To256 ( DestBuffer+Offset, SrcBuffer, DestWd,
  272.                                    Error, AddError );
  273.                 SrcBuffer = Image->SetOffset ( Sx, Sy+(i*DivV)/MagV );
  274.                 Offset += BytesPerRow;
  275.                 if (Offset>(LONG)0xFFFF)
  276.                   {
  277.                     Offset &= 0xFFFF;
  278.                     Page++;  
  279.                     SetVESABank ( Page ); 
  280.                   } // End if
  281.               } // End for
  282.           } // End else                         
  283.       } // End if
  284.   } // End of DisplayImage for VESADRIVER
  285.  
  286. VOID VESADRIVER::DrawLine ( HDISPLAY hDisplay, LONG x1, LONG y1, LONG x2, LONG y2,
  287.                             COLOR  Color )
  288.   {
  289.     INT Dx, Dy;
  290.     INT AddX,AddY;
  291.     INT Len;
  292.  
  293.     if (hDisplay)
  294.       {}
  295.  
  296.     if (x2<x1)
  297.       {
  298.         AddX = -1;
  299.       } // End if
  300.     else
  301.       AddX = 1;
  302.  
  303.     Dx = abs(x2-x1);
  304.     Dy = abs(y2-y1);
  305.  
  306.     Len = MaxValue ( Dx, Dy ) + 1;
  307.  
  308.     BYTE *Buffer;
  309.     DWORD Offset;
  310.  
  311.     #if defined (__32BIT__)
  312.       #if defined (__FORDOS4GW__)
  313.         Buffer = (BYTE*)0xA0000;
  314.       #endif
  315.     #else
  316.       Buffer = (BYTE*)MK_FP(0xA000,0);
  317.     #endif
  318.  
  319.     AddY = BytesPerRow;
  320.     Offset = ((y1*AddY)&0xFFFF);
  321.  
  322.     LONG BankNumber = y1>>6;
  323.     SetVESABank ( BankNumber );
  324.  
  325.     INT i;
  326.     DWORD Error=0;
  327.  
  328.     DWORD x;
  329.  
  330.     if (Dy==0)
  331.       {
  332.         x = MinValue ( x1, x2 );
  333.         int i;
  334.         Buffer+=x;
  335.         for (i=0;i<Len;i++)
  336.           Buffer[Offset+i] = (BYTE)Color;
  337.         //memset ( Buffer+x, Color, Len );
  338.       } // End if
  339.     else
  340.       {
  341.         x = x1;
  342.         if (Dx>Dy)
  343.           {
  344.             for (i=0;i<Len;i++)
  345.               {
  346.                 Buffer[Offset+x] = (BYTE)Color;
  347.                 Error += (DWORD)Dy;
  348.                 if (Error>=(DWORD)Dx)
  349.                   {
  350.                     Offset += (DWORD)AddY;
  351.                     if (Offset>(DWORD)0xFFFF)
  352.                       {
  353.                         Offset &= (DWORD)0xFFFF;
  354.                         BankNumber ++;
  355.                         SetVESABank ( BankNumber );
  356.                       } // End Buffer
  357.                     Error -= Dx;
  358.                   } // End Error
  359.                 x += AddX;
  360.               } // End for
  361.           } // End if
  362.         else
  363.           {
  364.             for (i=0;i<Len;i++)
  365.               {
  366.                 Buffer[Offset+x] = (BYTE)Color;
  367.                 Error += (DWORD)Dx;
  368.                 if (Error>=(DWORD)Dy)
  369.                   {
  370.                     x += AddX;
  371.                     Error -= (DWORD)Dy;
  372.                   } // End Error
  373.                 Offset += (DWORD)AddY;
  374.                 if (Offset>(DWORD)0xFFFF)
  375.                   {
  376.                     Offset &= (DWORD)0xFFFF;
  377.                     BankNumber ++;
  378.                     SetVESABank ( BankNumber );
  379.                   } // End Buffer
  380.               } // End for
  381.           } // End else
  382.       } // End else
  383.   } // End of DrawLine for VESADRIVER
  384.  
  385. VOID VESADRIVER::DrawRect ( HDISPLAY hDisplay, LONG x1, LONG y1, LONG x2, LONG y2,
  386.                             COLOR Color )
  387.   {
  388.     DrawLine ( hDisplay, x1, y2, x2, y2, Color );
  389.     DrawLine ( hDisplay, x1, y1, x2, y1, Color );
  390.     DrawLine ( hDisplay, x1, y1, x1, y2, Color );
  391.     DrawLine ( hDisplay, x2, y1, x2, y2, Color );
  392.   } // End of DrawRect for VESADRIVER
  393.  
  394. VOID VESADRIVER::FillRect ( HDISPLAY hDisplay, LONG x1, LONG y1, LONG x2, LONG y2,
  395.                            COLOR Color )
  396.   {
  397.     BYTE *Buffer;
  398.  
  399.     if (hDisplay)
  400.       {}
  401.  
  402.     #if defined (__32BIT__)
  403.       #if defined (__FORDOS4GW__)
  404.         Buffer = (BYTE*)0xA0000;
  405.       #endif
  406.     #else
  407.       Buffer = (BYTE*)MK_FP(0xA000,0);
  408.     #endif
  409.  
  410.     LONG AddY = BytesPerRow;
  411.     LONG Offset;
  412.     Offset = y1*AddY+x1;
  413.     Offset &= (DWORD)0xFFFF;
  414.  
  415.     LONG BankNumber;
  416.     BankNumber = y1>>6;
  417.     SetVESABank ( BankNumber );
  418.  
  419.     INT i;
  420.     LONG Wd, Ht;
  421.  
  422.     Wd = x2-x1+1;
  423.     Ht = y2-y1+1;
  424.  
  425.     for (i=0;i<Ht;i++)
  426.       {
  427.         memset ( Buffer+Offset, Color, Wd );
  428.         Offset += AddY;
  429.         if (Offset>(DWORD)0xFFFF)
  430.           {
  431.             Offset &= (DWORD)0xFFFF;
  432.             BankNumber++;
  433.             SetVESABank ( BankNumber );
  434.           } // End Buffer
  435.       } // End for
  436.   } // End of FillRect for VESADRIVER
  437.  
  438. VOID VESADRIVER::DrawPixel ( HDISPLAY hDisplay, LONG x, LONG y,
  439.                             COLOR Color )
  440.   {
  441.     if (hDisplay)
  442.       {}
  443.  
  444.     if ((x<0)||(x>=Width))
  445.       return;
  446.     if ((y<0)||(y>=Height))
  447.       return;
  448.  
  449.     #if defined (__32BIT__)
  450.       #if defined (__FORWATCOM__)
  451.         Buffer = (BYTE*)0xA0000;
  452.       #endif
  453.     #else
  454.       Buffer = (BYTE*)MK_FP(0xA000,0);
  455.     #endif
  456.  
  457.     LONG Offset;
  458.     Offset = y*BytesPerRow+x;
  459.     Offset &= (DWORD)0xFFFF;
  460.  
  461.     LONG BankNumber;
  462.     BankNumber = y>>6;
  463.     SetVESABank ( BankNumber );
  464.  
  465.     *(Buffer+Offset) = (BYTE)Color;
  466.   } // End of DrawPixel for VESADRIVER
  467.  
  468. VOID VESADRIVER::DrawHorizLine ( HDISPLAY hDisplay, LONG x1, LONG x2, LONG y, COLOR Color )
  469.   {
  470.     if (hDisplay)
  471.       {}
  472.  
  473.     if (x1>x2)
  474.       SwapValue ( &x1, &x2 );
  475.  
  476.     if (x1<0)
  477.       x1 = 0;
  478.     else if (x1>Width)
  479.       return;
  480.  
  481.     if (x2<0)
  482.       return;
  483.     else if (x2>Width)
  484.       x2 = Width;
  485.  
  486.     if (y<0)
  487.       y = 0;
  488.     else if (y>Height)
  489.       return;
  490.  
  491.     INT Wd;
  492.  
  493.     Wd = x2 - x1 + 1;
  494.  
  495.     BYTE *Buffer;
  496.  
  497.     #if defined (__32BIT__)
  498.       #if defined (__FORWATCOM__)
  499.         Buffer = (BYTE*)0xA0000;
  500.       #endif
  501.     #else
  502.       Buffer = (BYTE*)MK_FP(0xA000,0);
  503.     #endif
  504.  
  505.     LONG Offset = y*BytesPerRow+x1;
  506.     Offset &= (DWORD)0xFFFF;
  507.  
  508.     SetVESABank ( y>>6 );
  509.  
  510.     memset ( Buffer+Offset, Color, Wd );
  511.   } // End of DrawHorizLine for VESADRIVER
  512.  
  513.